#ifndef CLIENTOPERATION_H
#define CLIENTOPERATION_H

#include <QObject>
#include "seckeyshm.h"
#include "requestcodec.h"
#include "respondcodec.h"
#include "rsacrypto.h"

// 类声明
class ClientOperation;
typedef void (*callback1)(RequestInfo& info, RsaCrypto &rsa, ClientOperation* cliop);
typedef void (*callback2)(RespondInfo& resInfo, ClientOperation* obj);
// 定义结构体, 作为参数传递给任务函数 -> communication
struct ArgInfo
{
    callback1 prepare;
    callback2 dispose;
    ClientOperation* object;    // 当前任务类的实例对象
};

class ClientOperation : public QObject
{
    Q_OBJECT
public:
    enum CmdType{Consult, Verify, Logout, Login};
    explicit ClientOperation(QObject *parent = nullptr);

    // 功能函数
    // 秘钥协商 --> 作为一个问题添加到任务队列中, 应该和任务的类型一致
    // 如果在静态函数中要访问对的非静态成员函数/变量, 应该通过参数传递一个
    // 当前类的实例对象到静态函数体内部, 通过这个实例调用进行调用即可
    static void consultPrepare(RequestInfo& info, RsaCrypto &rsa, ClientOperation* cliop);
    static void consultDispose(RespondInfo& resInfo, ClientOperation* obj);

    // 秘钥校验
    static void verifyPrepare(RequestInfo& info, RsaCrypto &rsa, ClientOperation* cliop);
    static void verifyDispose(RespondInfo& resInfo, ClientOperation* obj);

    // 秘钥注销
    static void logoutPrepare(RequestInfo& info, RsaCrypto &rsa, ClientOperation* cliop);
    static void logoutDispose(RespondInfo& resInfo, ClientOperation* obj);

    // 登录
    static void loginPrepare(RequestInfo& info, RsaCrypto &rsa, ClientOperation* cliop);
    static void loginDispose(RespondInfo& resInfo, ClientOperation* obj);

    // 秘钥协商, 秘钥校验, 秘钥注销, ....通信的处理流程函数
    // 只是主流程, 没有具体的处理动作
    // 这是一个任务函数, 要添加到任务队列中, 在添加任务的时候,通过参数将需要的数据传递到函数内部
    // 需要的数据: 不同的请求对应的具体的处理动作(函数)
    // - 传递两个函数地址: xxxPrepare() / xxxDispose()
    static void communication(void* arg);

    // 添加最后一个任务, 让线程工作, 工作期间就可以退出子线程了
    static void lastTask(void* arg);

public slots:
    void saveLoginInfo(QString id, QString pwd);

signals:
    // 信号不能直接在静态函数中使用, 需要使用类的实例对象调用完成发送
    void sendMsg(QString msg);
    // 登录成功
    void loginSuccess();
    // 登录失败
    void loginFail();

private:
    SeckeyShm *m_shm;   // 共享内存的对象
    QString m_netID;
    QString m_passwd;
};

#endif // CLIENTOPERATION_H
